﻿// (c) Copyright 2013 Mike Riedel.
// This source is subject to the Microsoft Public License (Ms-PL).
// All other rights reserved.

using System;
using System.Threading.Tasks;

namespace FreshMeat.Threading
{
   /// <summary>
   /// Defines a lock that regulates access to a resource by multiple threads.
   /// </summary>
   public interface ILock
   {
      /// <summary>
      /// Waits until the protected resource is available for access by the calling thread.
      /// </summary>
      void Wait();

      /// <summary>
      /// Waits until the protected resource is available for access by the calling thread.
      /// </summary>
      /// <returns></returns>
      Task WaitAsync();

      /// <summary>
      /// Indicates the calling threading is done accessing the resource.
      /// </summary>
      void Done();

      /// <summary>
      /// Performs a <see cref="Wait"/> and then returns a <see cref="IDisposable"/>
      /// object that will call <see cref="Done"/> when it is disposed.
      /// The typical usage pattern is to put this into a <code>using</code> block containing
      /// the code which read from the protected resource; this avoid the the common usage
      /// of forgetting to call <see cref="Done"/>.
      /// </summary>
      /// <returns>Object which must be disposed.</returns>
      IDisposable Context();
   }
}